#ifndef ATOM_H_
#define ATOM_H_

#if !defined(__i386__) && !defined(__x86_64__)
#error "not support architecture"
#else
static inline int
atomic_add(volatile int *lhs, int rhs) {
#ifdef __linux__
	__asm__ __volatile__(
			"lock xadd %0, (%1);"
			: "=a" (rhs)
			: "r" (lhs), "a" (rhs)
			: "memory"
		);
#else
#error "not linux system"
#endif
	return rhs;
}

static inline int
atomic_swap(volatile void* lhs, int rhs) {
#ifdef __linux__
	__asm__ __volatile__(
			"lock xchg %0, (%1);"
			: "=a" (rhs)
			: "r"(lhs), "a"(rhs)
			: "memory"
			);
#else
#error "not linux system"
#endif
	return rhs;
}

//注意gcc汇编操作数的顺序
//如果comperand == lhs 则将rhs装载到lhs
//如果comperand != lhs 则不装载
//最终返回lhs的值
static inline int
atomic_comp_swap(volatile void* lhs, int rhs, int comperand) {
#ifdef __linux__
	//cmpxchg命令:	如果eax等于第一个操作数，则将第二个操作数存入第一个
	//			  	如果eax不等于第一个操作数，则第一操作数放入eax
	//如果
	__asm__ __volatile__(
			"lock cmpxchg %1, (%2);" //(%2)对第二个操作数取值
			: "=a" (comperand)
			: "d"(rhs), "r"(lhs), "a"(comperand)
			);
#else
#error "not linux system"
#endif
	return comperand;
}

#define AtomicGet(x) (atomic_comp_swap(&(x), 0, 0))
#define AtomicSet(x, v) (atomic_swap(&(x), (v)))
#define AtomicSetIf(x, v, ifn) (atomic_comp_swap(&(x), (v), ifn)) 
#define AtomicAdd(x,v) (atomic_add(&(x), (v)))
#endif
#endif
